import { IPanelContainer } from '@ibiz/model-core';
import { useNamespace } from '@ibiz-template/vue3-util';
import {
  ref,
  watch,
  PropType,
  nextTick,
  onMounted,
  onUnmounted,
  defineComponent,
} from 'vue';
import { PanelDraggableContainerController } from './panel-draggable-container.controller';
import { Windowing, Minimize } from './svg-icon';
import './panel-draggable-container.scss';

export const PanelDraggableContainer = defineComponent({
  name: 'IBizPanelDraggableContainer',
  props: {
    modelData: { type: Object as PropType<IPanelContainer>, required: true },
    controller: {
      type: Object as PropType<PanelDraggableContainerController>,
      required: true,
    },
  },
  setup(props, { slots }) {
    const ns = useNamespace('panel-draggable-container');
    const { containerClass, state, model } = props.controller;

    const container = ref<HTMLDivElement | undefined>();

    onMounted(() => props.controller.initDraggable());

    onUnmounted(() => props.controller.interactable?.unset());

    /**
     * @description 改变窗口
     * @returns {*}
     */
    const changeWindow = (): void => {
      if (!container.value) return;
      if (state.showMode !== 'window') {
        state.showMode = 'window';
        nextTick(() => {
          Object.assign(container.value!.style, {
            top: `100px`,
            width: `${state.minWidth}px`,
            height: `${state.minHeight}px`,
            left: `${window.innerWidth - state.minWidth - 100}px`,
          });
        });
      } else {
        state.showMode = 'default';
      }
    };

    /**
     * @description 改变最小化
     */
    const changeMinimize = () => {
      state.showMode = state.showMode !== 'minimize' ? 'minimize' : 'default';
    };

    watch(
      () => state.showMode,
      (newVal, oldVal) => {
        const opt = {
          allowDrag: newVal !== 'minimize',
          allowDragBorder: newVal === 'window',
        };
        props.controller.updateDragOpt(opt);
      },
    );

    /**
     * @description 绘制内容
     * @returns {*}
     */
    const renderContent = () => {
      return (
        <div
          ref='container'
          class={[
            ns.b(),
            ns.m(model.id),
            ...containerClass,
            ns.m(state.showMode),
            ns.is('hidden', !state.visible),
          ]}
          v-loading={state.loading}
          style={{ width: `${state.minWidth}px` }}
          onClick={event => props.controller.onClick(event)}
        >
          {model.cssStyle ? (
            <style type='text/css'>{model.cssStyle}</style>
          ) : null}
          <div class={[ns.e('header'), 'drag-handle']}>
            <div class={ns.em('header', 'caption')}>{model.caption}</div>
            <div class={ns.em('header', 'actions')}>
              <span
                title='窗口化'
                v-html={Windowing}
                class={[
                  ns.e('icon'),
                  ns.is('actived', state.showMode === 'window'),
                ]}
                onClick={changeWindow}
              ></span>
              <span
                title='最小化'
                v-html={Minimize}
                class={[
                  ns.e('icon'),
                  ns.is('actived', state.showMode === 'minimize'),
                ]}
                onClick={changeMinimize}
              ></span>
            </div>
          </div>
          <iBizRow slot='content' class={ns.e('content')} layout={model.layout}>
            {slots.default?.()?.map(slot => {
              const props = slot.props as IData;
              if (!props || !props.controller) return slot;
              const state = props.controller.state;
              const showNoData =
                props.controller.model.id === 'nav_pos' &&
                (!state.currentKey || state.currentKey === '___');
              return (
                <iBizCol
                  class={[
                    ns.em('content', 'item'),
                    ns.is('show-no-data', showNoData),
                  ]}
                  state={props.controller.state}
                  layoutPos={props.modelData.layoutPos}
                >
                  {showNoData && <iBizNoData />}
                  {slot}
                </iBizCol>
              );
            })}
          </iBizRow>
        </div>
      );
    };

    /**
     * @description 绘制最小化
     * @returns {*}
     */
    const renderMinimize = () => {
      return (
        <el-popover
          placement='left'
          width={state.minWidth + 24}
          popper-class={ns.e('popover')}
          class={[ns.e('minimize'), ns.is('hidden', !state.visible)]}
        >
          {{
            reference: () => (
              <el-button size='small' class={ns.em('minimize', 'button')}>
                详情
              </el-button>
            ),
            default: () => renderContent(),
          }}
        </el-popover>
      );
    };

    return { ns, container, renderContent, renderMinimize };
  },
  render() {
    const { state } = this.controller;
    return state.showMode === 'minimize'
      ? this.renderMinimize()
      : this.renderContent();
  },
});
